/*Z OK GNU Multiboot规范 */

/*
 * Copyright 2014, General Dynamics C4 Systems
 *
 * SPDX-License-Identifier: GPL-2.0-only
 */

#pragma once
/* Adapted from the MultiBoot Specification:  */
/* www.gnu.org/software/grub/manual/multiboot */
/*Z boot loader向OS出示的识别记号 */
#define MULTIBOOT_MAGIC 0x2BADB002

#include <types.h>
#include <sel4/arch/bootinfo_types.h>
/*Z Multiboot boot loader加载的模块信息 */
typedef struct multiboot_module {
    uint32_t  start;            /*Z 起始地址 */
    uint32_t  end;              /*Z 结束地址(应该是不包含) */
    uint32_t  name;             /*Z 模块名字符串（C样式）地址，0表示没有 */
    uint32_t reserved;
} PACKED multiboot_module_t;
/*Z RAM区域图信息块 */
typedef struct multiboot_mmap {
    uint32_t size;              /*Z 本数据结构大小（字节）*/
    uint64_t base_addr;         /*Z 本区域起始地址。mmap_addr指向的是这个位置 */
    uint64_t length;            /*Z 本区域大小（字节）*/
    uint32_t type;              /*Z 1-可用RAM，3-ACPI，4-hibernation，5-缺陷，其它-保留 */
} PACKED multiboot_mmap_t;
/*Z Multiboot兼容的boot loader传递的引导信息块 */
typedef struct multiboot_info {
    /* struct split into multiple parts due to details of how C parser works */
    struct multiboot_part1 {
        uint32_t flags;         /*Z 指示以下各项是否存在 */
        uint32_t mem_lower;     /*Z 0：0开始的内存大小，最大640K，单位KB */
        uint32_t mem_upper;     /*Z 0：1M开始至第一个hole的内存大小，单位KB */
        uint32_t boot_device;   /*Z 1：加载磁盘：高字节0x80表示第一块硬盘，后面依次为分区、子分区0开始的编号(4逻辑分区，0xFF未用) */
        uint32_t cmdline;       /*Z 2：命名行字符串（C样式）的物理地址 */
        uint32_t mod_count;     /*Z 3：加载的模块数量 */
        uint32_t mod_list;      /*Z 3：第一个模块信息的物理地址，该信息包括：模块起始、结束地址、名字、保留字，大小可能为16B */
    } part1;
    /* The symbol table information in the multiboot header is comprised of a union
     * as we neither a. support unions in the kernel or b. need the symbol information
     * we will just skip the 4 words of this */
    struct multiboot_part2 {
        uint32_t syms[4];           /*Z 4：a.out，5：ELF 有关符号表信息 */
        uint32_t mmap_length;       /*Z 6：RAM区域图信息块总大小 */
        uint32_t mmap_addr;         /*Z 6：RAM区域图第一个区域信息的物理地址 */
        uint32_t drives_length;     /*Z 7：驱动器信息块总大小 */
        uint32_t drives_addr;       /*Z 7：第一个驱动器信息块的物理地址 */
        uint32_t config_table;      /*Z 8：BIOS配置信息表的物理地址 */
        uint32_t boot_loader_name;  /*Z 9：boot loader的C样式的名字串地址 */
        uint32_t apm_table;         /*Z 10：APM信息块的物理地址 */
        uint32_t vbe_control_info;  /*Z 11：以下各项是关于VBE-VESA Bios Extension信息的 */
        uint32_t vbe_mode_info;     /*Z 显示模式信息的地址 */
        uint16_t vbe_mode;
        uint16_t vbe_interface_seg; /*Z 32位保护模式下的VESA功能调用地址，此项是段地址 */
        uint16_t vbe_interface_off; /*Z                                         偏移量 */
        uint16_t vbe_interface_len; /*Z 该功能调用代码块的总长度 */
    } part2;    /*Z 后面还有关于图形显示缓存的信息，seL4忽略了 */
} PACKED multiboot_info_t;

#define MULTIBOOT_INFO_MEM_FLAG     BIT(0)
#define MULTIBOOT_INFO_CMDLINE_FLAG BIT(2)
#define MULTIBOOT_INFO_MODS_FLAG    BIT(3)
#define MULTIBOOT_INFO_MMAP_FLAG    BIT(6)
#define MULTIBOOT_INFO_GRAPHICS_FLAG BIT(11)
#define MULTIBOOT_MMAP_USEABLE_TYPE     1       /*Z 对应前面RAM区域图信息块type */
#define MULTIBOOT_MMAP_RESERVED_TYPE    2
#define MULTIBOOT_MMAP_ACPI_TYPE        3
#define MULTIBOOT_MMAP_ACPI_NVS_TYPE    4
#define MULTIBOOT_MMAP_BAD_TYPE         5

